package org.shop.controller.pay;

import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.PublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.shop.controller.pay.util.RSAUtil;
import org.shop.controller.pay.util.ResponseHandler;
import org.shop.controller.pay.util.XMLUtil;
import org.shop.entity.OrderSettlements;
import org.shop.entity.Orders;
import org.shop.entity.Supplier;
import org.shop.entity.Users;
import org.shop.entity.security.MyUserDetail;
import org.shop.service.OrderSettlementsService;
import org.shop.service.OrdersService;
import org.shop.service.SupplierService;
import org.shop.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;

/**
 * 微信支付管理
 * @author zym
 * @version 1.0.1
 */
@Controller
public class WxPayController{
	
	private static Logger logger = LogManager.getLogger(WxPayController.class);
	
	@Autowired
	private OrdersService ordersService;
	@Autowired
	private UserService userService;
	@Autowired
	private OrderSettlementsService orderSettlementsService;
    @Autowired
	private SupplierService supplierService;
    
    String apiKey="ruifight2018ruifight201820182018";
    String appId="wx2bd673080e67273b";
    String matchId="1507157911";



    /**
     * 微信公从号支付（根据订单号)
     * @param request
     * @param orderNo
     * @return
     */
    @RequestMapping("app/createWxH5Pay")
    @ResponseBody
    public Map<String,Object> createWxH5Pay(HttpServletRequest request) {
    	Map<String,Object> map = new HashMap<String,Object>();
    	Long orderId = Long.parseLong(request.getParameter("orderId"));
    	Orders orders = ordersService.selectByPrimaryKey(orderId);
    	String str = "";
    	if (request.getHeader("x-forwarded-for") == null) {  
    		str = request.getRemoteAddr();  
    	}else {
    		str = request.getHeader("x-forwarded-for");  
    	}
        logger.info("微信H5页面支付(移动端非微信扫码支付):{}", orders.getOrderNo());
        BigDecimal wxPrice = orders.getOrderPrice().multiply(new BigDecimal(100));
        logger.info("订单金额------"+rvZeroAndDot(wxPrice.toString()));
//        Date curDate=new Date();
        TreeMap<String, String> params = new TreeMap<String, String>();
        String payNo = orders.getOrderNo();
        String url = "http://" + request.getServerName() + ":"+ request.getServerPort()+ request.getContextPath()+"/app/huidiao";
        String urlScene_info = "http://" + request.getServerName() + ":"+ request.getServerPort()+ request.getContextPath();
   		logger.info("url*****************"+url);
        String callbackUrl = url;
        params.put("appid", appId);
        params.put("mch_id", matchId);
        params.put("device_info", "WEB");//自定义参数，可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
        params.put("nonce_str", WXPayUtil.getStringRandom(30));//随机字符串，长度要求在32位以内。推荐随机数生成算法
        params.put("body", "微信支付");//商品简单描述，该字段请按照规范传递，具体请见参数规定
        params.put("out_trade_no", orders.getOrderNo());// 商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*@ ，且在同一个商户号下唯一。详见商户订单号curDate.getTime()+""
        params.put("total_fee", rvZeroAndDot(wxPrice.toString()));//订单总金额，单位为分，详见支付金额（******特别注意后面不能有点不能有零）
        params.put("spbill_create_ip", str);//APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。
        params.put("notify_url", callbackUrl);//异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
        params.put("trade_type", "MWEB");// 取值如下：JSAPI--公众号支付，NATIVE--原生扫码支付，APP--app支付等，说明详见参数规定
        params.put("attach", "3");//附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用  1 公众号支付 2 扫码支付 3 h5支付+"&redirect_url=http%3A%2F%2Fumumu.cn%2Fapp%2FgetSuccess"
        params.put("scene_info", "'h5_info':{'type':'Wap','wap_url':'"+urlScene_info+"','wap_name': 'csg测试'}");
        String sign = null;
        try {
            sign = WXPayUtil.createSign("UTF-8", params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        params.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
        logger.info("发送的报文:" + JSON.toJSONString(params));
        String retXml = WxHttpClientUtils.reqPost(WXPayConstants.UNIFIEDORDER_URL_SUFFIX, WXPayUtil.map2Xml(params));
        System.err.println("xml is \t\t"+retXml);
        logger.info("微信预付单返回:" + retXml);
        Map<String,String> obj=null;
        String rtnUrl="";
        String urlRetuen = "http%3A%2F%2F" + request.getServerName() + "%3A"+ request.getServerPort()+ request.getContextPath()+"%2Fapp%2FpromptSuccess%3FpayNo%3D"+payNo;
        try{
            obj= WXPayUtil.xmlToMap(retXml);
            rtnUrl=obj.get("mweb_url")+"&redirect_url="+urlRetuen;
            logger.info("rtnUrl isisis***********" +rtnUrl);
            logger.info("urlRetuen -----------------------------" +urlRetuen);
        }catch (Exception e){
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        logger.info("===============================================================");
        map.put("rtnUrl", rtnUrl);
        return map;
    }

    
    /**
     * 微信扫码支付
     * @param request
     * @param orderNo 订单号
     * @return
     */
    @RequestMapping("common/createWxQRPay")
    @ResponseBody
    public Object createWxQRPay(HttpServletRequest request) {
    	//获取登录人用户信息
//    	MyUserDetail ud = (MyUserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    	Date curDate=new Date();
    	String outTradeNo = curDate.getTime()+"";
        logger.info("微信扫码支付订单号:{}",outTradeNo);
        TreeMap<String, String> params = new TreeMap<String, String>();
        String url = "http://" + request.getServerName() + ":"+ request.getServerPort()+ request.getContextPath()+"/web/huidiao";
   		logger.info("url*****************"+url);
        String callbackUrl = url;
        params.put("appid", appId);
        params.put("mch_id", matchId);
        params.put("device_info", "WEB");//自定义参数，可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
        params.put("nonce_str", WXPayUtil.getStringRandom(30));//随机字符串，长度要求在32位以内。推荐随机数生成算法
        params.put("body", "微信支付");//商品简单描述，该字段请按照规范传递，具体请见参数规定
        request.getSession().setAttribute("outTradeNo", outTradeNo);
        params.put("out_trade_no", outTradeNo);// 商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|*@ ，且在同一个商户号下唯一。详见商户订单号
        params.put("total_fee", 1+"");//订单总金额，单位为分，详见支付金额
        params.put("spbill_create_ip", request.getRemoteAddr());//APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。
        params.put("notify_url", callbackUrl);//异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
        params.put("trade_type", "NATIVE");// 取值如下：JSAPI--公众号支付，NATIVE--原生扫码支付，APP--app支付等，说明详见参数规定
        params.put("attach", "2");//附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用
        String sign = null;
        try {
            sign = WXPayUtil.generateSignature(params,apiKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        params.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
        logger.info("发送的报文:" + JSON.toJSONString(params));
        String retXml = WxHttpClientUtils.reqPost(WXPayConstants.UNIFIEDORDER_URL_SUFFIX, WXPayUtil.map2Xml(params));
        logger.info("微信预付单返回:" + retXml);
        Map<String,String> obj=null;
        String qrCodeUrl="";
        try{
            obj= WXPayUtil.xmlToMap(retXml);
            if(ObjectUtils.isNotEmpty(obj)){
                qrCodeUrl= obj.get("code_url");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        logger.info("===============================================================");
        return qrCodeUrl;
    }
    
    
	   /**
	    * h5支付异步回调接口 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
   @RequestMapping(value="/app/huidiao",produces="text/html;charset=utf-8")  
   @ResponseBody  
   public String WeixinParentNotifyPage(HttpServletRequest request,HttpServletResponse response) throws Exception{  
	   Map<String,Object> paramMap = new HashMap<String,Object>();
	   logger.info("****************************************");
	   logger.info("app/huidiaoapp/huidiaoapp/huidiaoapp/huidiaoapp/huidiaoapp/huidiaoapp/huidiaoapp/huidiaoapp/huidiaoapp/huidiao");
       ServletInputStream instream = request.getInputStream();  
       StringBuffer sb = new StringBuffer();  
       int len = -1;  
       byte[] buffer = new byte[1024];  
         
       while((len = instream.read(buffer)) != -1){  
           sb.append(new String(buffer,0,len));  
       }  
       instream.close();  
       logger.info("sb is \t\t****"+sb);
       ResponseHandler resHandler = null;
       SortedMap<String,String> map = null;
       Map<String,String> return_data = null;
       try {
    	   map = XMLUtil.doXMLParse2(sb.toString());//接受微信的通知参数  
    	   return_data = new HashMap<String,String>(); 
         //创建支付应答对象  
           resHandler = new ResponseHandler(request, response);  
           resHandler.setAllparamenters(map);  
           resHandler.setKey(apiKey);  
       //判断签名  
       if(resHandler.isTenpaySign()){  
           if(!map.get("return_code").toString().equals("SUCCESS")){  
               return_data.put("return_code", "FAIL");  
               return_data.put("return_msg", "return_code不正确");  
           }else{  
               if(!map.get("result_code").toString().equals("SUCCESS")){  
                   return_data.put("return_code", "FAIL");  
                   return_data.put("return_msg", "result_code不正确");  
               }  
                 
               String out_trade_no = map.get("out_trade_no").toString(); 
               paramMap.put("orderNo", out_trade_no);
               logger.error("out_trade_no   is \t\t"+out_trade_no);
               //获取交易时间
//               String time_end = map.get("time_end").toString();  
               BigDecimal total_fee = new BigDecimal(map.get("total_fee").toString());  
               Orders orderInfo = ordersService.getOrder(paramMap);
               //付款完成后,发送该交易状态通知  
               logger.info("付款的状态----------"+orderInfo.getOrderStatus());
               BigDecimal wxPrice = orderInfo.getOrderPrice().multiply(new BigDecimal(100));
               if(orderInfo == null|| "".equals(orderInfo)){  
                   System.out.println("订单不存在");  
                   logger.info("-----订单不存在-----");
                   return_data.put("return_code", "FAIL");  
                   return_data.put("return_msg", "订单不存在");  
                   return WXPayUtil.mapToXml(return_data);
               //如果订单已经支付返回错误
               }else if(orderInfo.getOrderStatus()>=3) {
            	 logger.info("-----订单已经支付-----");  
                 System.out.println("订单已经支付");  
                 return_data.put("return_code", "SUCCESS");  
                 return_data.put("return_msg", "OK");  
                 return WXPayUtil.mapToXml(return_data);
               //如果支付金额不等于订单金额返回错误
               }else if(!total_fee.toString().equals(rvZeroAndDot(wxPrice.toString()))) {
            	 logger.info("-----资金异常-----"); 
            	 logger.info("-----微信支付的资金-----"+total_fee.toString()); 
            	 logger.info("-----后台数据的资金-----"+rvZeroAndDot(wxPrice.toString())); 
                 System.out.println("资金异常");  
                 return_data.put("return_code", "FAIL");  
                 return_data.put("return_msg", "金额异常");  
                 return WXPayUtil.mapToXml(return_data); 
               }else {
            	   orderInfo.setOrderStatus((byte) 3);
            	   orderInfo.setIsPay((byte) 1);
            	   orderInfo.setPayFrom((byte) 2);
            	   int num = ordersService.updateByPrimaryKeySelective(orderInfo);
            	   if(num>0) {
            		   logger.info("-----修改状态成功！！！！！！！！！！！！！！！！！！！！！！！！！-----"); 
            		   return_data.put("return_code", "SUCCESS");  
                       return_data.put("return_msg", "OK");  
                       return WXPayUtil.mapToXml(return_data); 
            	   }else{  
            		   logger.info("-----修改状态！！！！！！！！！！！！！！！！！！！！！！！！！-----"); 
            		   return_data.put("return_code", "FAIL");  
            		   return_data.put("return_msg", "支付失败");  
            		   return WXPayUtil.mapToXml(return_data);  
        	   	   }  
               }  
               //更新订单信息  
//               if(orderdao.PaymentEndUpdateOrder(out_trade_no, time_end)){  
//                   System.out.println("更新订单成功");  
                   //如果该订单是幼儿产品  并且 存在代理  
//                   if(order_type == 2){  
//                       if(supplier_id != 0){  
//                           Map su = userdao.getSupplierInfo(supplier_id);  
//                           String phone = (String) su.get("phone_number");  
//                           String nickname = (String) su.get("nickname");  
//                           String app_token = (String) su.get("app_token");  
//                             
//                           String content = "【三盛科创】尊敬的"+ nickname +"您好。您在我们平台出售的商品有新用户下单。请您点击该链接查看发货信息。"+Config.WEB_SERVER+"/order/SupplierOrderInfo.do?order_number="+out_trade_no+"&sid="+app_token+".请您务必妥善包管。";  
//                           MessageUtil.SendMessage(phone,content);  
//                       }  
//                   }else{  
//                       orderdao.UpdateOrderStatus(out_trade_no, 3);//更新订单为已完成  
//                   }  

           }  
       }else{  
           return_data.put("return_code", "FAIL");  
           return_data.put("return_msg", "签名错误");  
       }  
       }catch(Exception e) {
    	   e.printStackTrace();
    	   logger.info(e.getMessage());
       } 
       return WXPayUtil.mapToXml(return_data); 
   } 
   /**
    * web扫码异步回调接口 
    * @param request
    * @param response
    * @return
    * @throws Exception
    */
   @RequestMapping(value="/web/huidiao",produces="text/html;charset=utf-8")  
   @ResponseBody  
   public String webWeixinParentNotifyPage(HttpServletRequest request,HttpServletResponse response) throws Exception{ 
	   Map<String,Object> pramMap = new HashMap<String,Object>();
	   logger.info("****************************************");
	   ServletInputStream instream = request.getInputStream();  
	   StringBuffer sb = new StringBuffer();  
	   int len = -1;  
	   byte[] buffer = new byte[1024];  
	   
	   while((len = instream.read(buffer)) != -1){  
		   sb.append(new String(buffer,0,len));  
	   }  
	   instream.close();  
	   ResponseHandler resHandler = null;
	   SortedMap<String,String> map = null;
	   Map<String,String> return_data = null;
	   try {
		   map = XMLUtil.doXMLParse2(sb.toString());//接受微信的通知参数  
		   return_data = new HashMap<String,String>(); 
		   //创建支付应答对象  
		   resHandler = new ResponseHandler(request, response);  
		   resHandler.setAllparamenters(map);  
		   resHandler.setKey(apiKey);  
		   //判断签名  
		   if(resHandler.isTenpaySign()){  
			   if(!map.get("return_code").toString().equals("SUCCESS")){  
				   return_data.put("return_code", "FAIL");  
				   return_data.put("return_msg", "return_code不正确");  
			   }else{  
				   if(!map.get("result_code").toString().equals("SUCCESS")){  
					   return_data.put("return_code", "FAIL");  
					   return_data.put("return_msg", "result_code不正确");  
				   }else {
					   //订单号
					   String out_trade_no = map.get("out_trade_no").toString(); 
					   logger.error("out_trade_no   is \t\t"+out_trade_no);
					   //获取openid
					   String openid = map.get("openid").toString();
					   BigDecimal total_fee = new BigDecimal(map.get("total_fee").toString());  
					   System.err.println("支付的金额  is"+total_fee);
//					   pramMap.put("openID", openid);
//					   pramMap.put("loginName", out_trade_no);
//					   int num = userService.addOpenIdByLoginName(pramMap);
//					   System.err.println("是否添加opeinId成功  is"+num);
					   return_data.put("return_code", "SUCCESS");  
	                   return_data.put("return_msg", "OK");  
	                   return WXPayUtil.mapToXml(return_data);
				   } 
			   }  
		   }else{  
			   return_data.put("return_code", "FAIL");  
			   return_data.put("return_msg", "签名错误");  
		   }  
	   }catch(Exception e) {
		   e.printStackTrace();
		   logger.info(e.getMessage());
	   } 
	   return WXPayUtil.mapToXml(return_data); 
   } 
   
	 /**
	 * 给前端提示支付成功页面 
	 * @param req
	 * @return
	 */
   	@RequestMapping("app/promptSuccess")
	public String promptSuccess(HttpServletRequest req) {
   		logger.info("*******************！！！！！！这里是给前端提示成功的页面！！！！！！*****************************");  
   		String payNo = req.getParameter("payNo");
   		String url = "redirect:http://" + req.getServerName() + ":"+ req.getServerPort()+ req.getContextPath()+"/app/getUserOrderList?payNo="+payNo;
   		logger.info("url*****************"+url);
		try {
			if(payNo!=""&&payNo!=null) {
				logger.info("*******************！！！！！！接收到参数了！！！！！！*****************************");
	            logger.info("*******************！！！！！！!!!!!!!!!!!!!!!!!!!!！！！！！！*****************************");
	            return url;
			}else {
				return "访问错误";
			}
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            req.setAttribute("ifSuccess", 0);
        }
		return "访问错误";
	}
   
   
   
	/**
	 * 去零和逗好操作
	 * @param s
	 * @return
	 */
	public static String rvZeroAndDot(String s){  
	       if (s.isEmpty()) {
	    	   return null;
	       }
	       if(s.indexOf(".") > 0){  
	       s = s.replaceAll("0+?$", "");//去掉多余的0  
	       s = s.replaceAll("[.]$", "");//如最后一位是.则去掉  
	       }  
	      return s;  
	 }  
	
	/**
	 * 查询微信订单是否支付完成
	 * @param req
	 * @return
	 */
	@RequestMapping("app/queryWXPayState")
	@ResponseBody
	public Map<String,Object> queryWXPayState(HttpServletRequest req) {
		Map<String,Object> map = new HashMap<String,Object>();
		Map<String,String> mapWXResult = new HashMap<String,String>();
		Map<String,Object> orderInfoMap = new HashMap<String,Object>();
		TreeMap<String, String> params = new TreeMap<String, String>();
		String payNo = req.getParameter("orderNo");
		try {
			orderInfoMap = ordersService.getOrderAndGoodsInfoByOrderNo(payNo);
			map.put("orderInfoMap", orderInfoMap);
			params.put("appid", appId);
			params.put("mch_id", matchId);
			params.put("out_trade_no", payNo);
			params.put("nonce_str", WXPayUtil.getStringRandom(30));
		    String sign = null;
	        try {
	            sign = WXPayUtil.createSign("UTF-8", params);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	        params.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
	        mapWXResult = WxHttpClientUtils.queryWxDoXml(WXPayConstants.QUERYWXORDER, WXPayUtil.map2Xml(params));
	        map.put("mapWXResult", mapWXResult);
		}catch(Exception e) {
			e.printStackTrace();
			logger.info(e.getMessage());
		}
		return map;
	}
	
	/**
	 * 查询微信扫码支付完成
	 * @param req
	 * @return
	 */
	@RequestMapping("common/queryWebWXPayState")
	@ResponseBody
	public Map<String,Object> queryWebWXPayState(HttpServletRequest req) {
    	Object outTradeNo = req.getSession().getAttribute("outTradeNo");
		Map<String,Object> map = new HashMap<String,Object>();
		Map<String,String> mapWXResult = new HashMap<String,String>();
		TreeMap<String, String> params = new TreeMap<String, String>();
		String settlementId = req.getParameter("settlementId");
		try {
			if(outTradeNo!=null) {
				params.put("appid", appId);
				params.put("mch_id", matchId);
				params.put("out_trade_no", outTradeNo.toString());
				params.put("nonce_str", WXPayUtil.getStringRandom(30));
			    String sign = null;
		        try {
		            sign = WXPayUtil.createSign("UTF-8", params);
		        } catch (Exception e) {
		            e.printStackTrace();
		        }
		        params.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
		        mapWXResult = WxHttpClientUtils.queryWxDoXml(WXPayConstants.QUERYWXORDER, WXPayUtil.map2Xml(params));
		        map.put("mapWXResult", mapWXResult);
		        OrderSettlements os = new OrderSettlements();
		        //获取登录人用户信息
		    	MyUserDetail ud = (MyUserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		        if("SUCCESS".equals(mapWXResult.get("trade_state"))) {
		        	if(ObjectUtils.isEmpty(settlementId)) {
		        		if(ObjectUtils.isNotEmpty(ud.getMerchantId())) {
		        			os.setMerchantId(ud.getMerchantId());
		        		}else {
		        			Supplier supplier=supplierService.findSupplierByUserId(ud.getUserId());
		        			os.setSupplierId(supplier.getSupplierId());
		        		}
		        		os.setOpenId(mapWXResult.get("openid"));
						orderSettlementsService.insertSelective(os );
		        	}else{
		        		os.setSettlementId(Long.parseLong(settlementId));
		        		os.setOpenId(mapWXResult.get("openid"));
						orderSettlementsService.updateByPrimaryKeySelective(os );
		        	}
		        	
		        }
			}else {
				map.put("mapWXResult", null);
			}
		}catch(Exception e) {
			e.printStackTrace();
			logger.info(e.getMessage());
		}
		return map;
	}
	
	/**
	 * 查询微信扫码支付完成
	 * @param req
	 * @return
	 */
	@RequestMapping("common/queryWebWXPayState1")
	@ResponseBody
	public Map<String,Object> queryWebWXPayState1(HttpServletRequest req) {
		Object outTradeNo = req.getSession().getAttribute("outTradeNo");
		Map<String,Object> map = new HashMap<String,Object>();
		Map<String,String> mapWXResult = new HashMap<String,String>();
		TreeMap<String, String> params = new TreeMap<String, String>();
		try {
			if(outTradeNo!=null) {
				params.put("appid", appId);
				params.put("mch_id", matchId);
				params.put("out_trade_no", outTradeNo.toString());
				params.put("nonce_str", WXPayUtil.getStringRandom(30));
				String sign = null;
				try {
					sign = WXPayUtil.createSign("UTF-8", params);
				} catch (Exception e) {
					e.printStackTrace();
				}
				params.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
				mapWXResult = WxHttpClientUtils.queryWxDoXml(WXPayConstants.QUERYWXORDER, WXPayUtil.map2Xml(params));
				map.put("mapWXResult", mapWXResult);
			}else {
				map.put("mapWXResult", null);
			}
		}catch(Exception e) {
			e.printStackTrace();
			logger.info(e.getMessage());
		}
		return map;
	}
	
	
	 /**
     * 企业向个人微信支付转账(微信零钱)
     * @param request
     * @param response
     * @param callback
     */
    @RequestMapping(value = "/web/wxTx", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> transferPay(HttpServletRequest request, HttpServletResponse response, String callback) {
    	Map<String,Object> map = new HashMap<String,Object>();
        //业务判断 openid是否有收款资格
       	//获取登录人用户信息
    	MyUserDetail ud = (MyUserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    	Users findUserByLoginName = userService.findUserByLoginName(ud.getLoginName());
        Map<String, String> restmap = null;
        try {
            Map<String, String> parm = new HashMap<String, String>();
            parm.put("mch_appid", appId); //公众账号appid
            parm.put("mchid", matchId); //商户号
            parm.put("nonce_str", WXPayUtil.getStringRandom(30)); //随机字符串
            parm.put("partner_trade_no", ud.getLoginName()); //商户订单号
            parm.put("openid", findUserByLoginName.getOpenID()); //用户openid  
            parm.put("check_name", "NO_CHECK"); //校验用户姓名选项 OPTION_CHECK
            //parm.put("re_user_name", "安迪"); //check_name设置为FORCE_CHECK或OPTION_CHECK，则必填
            parm.put("amount", "1"); //转账金额
            parm.put("desc", "测试提现到个人"); //企业付款描述信息
            parm.put("spbill_create_ip", request.getRemoteAddr()); //服务器Ip地址
            String sign = null;
            try {
                sign = WXPayUtil.generateSignature(parm,apiKey);
            } catch (Exception e) {
                e.printStackTrace();
            }
            parm.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
            logger.info("发送的报文:" + JSON.toJSONString(parm));
            String retXml = WxHttpClientUtils.reqWithdrawalPost(WXPayConstants.TRANSFERS_PAY, WXPayUtil.map2Xml(parm));
            restmap = WXPayUtil.xmlToMap(retXml);
            logger.info("微信提现返回:" + retXml);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        if (restmap!=null && !"".equals(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
            logger.info("提现成功：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            Map<String, String> transferMap = new HashMap<>();
            transferMap.put("partner_trade_no", restmap.get("partner_trade_no"));//商户转账订单号
            transferMap.put("payment_no", restmap.get("payment_no")); //微信订单号
            transferMap.put("payment_time", restmap.get("payment_time")); //微信支付成功时间
            System.err.println("提现成功");
            map.put("msg", 1);
            map.put("partner_trade_no",restmap.get("partner_trade_no"));
        }else {
            if (restmap!=null && !"".equals(restmap)) {
                logger.info("提现失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            }
            System.err.println("提现失败");
            map.put("msg", 0);
        }
        return map;
    }
	
	
    /**
     * 企业向个人微信支付转账(银行卡)
     * @param request
     * @param response
     * @param callback
     */
    @RequestMapping(value = "/web/wxBankCardTx")
    @ResponseBody
    public Map<String,Object> transferBankCardPay(HttpServletRequest request, HttpServletResponse response, String callback) {
    	Map<String,Object> map = new HashMap<String,Object>();
    	PublicKey publicKey = null;
        //业务判断 openid是否有收款资格
       	//获取登录人用户信息
//    	MyUserDetail ud = (MyUserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//    	Users findUserByLoginName = userService.findUserByLoginName(ud.getLoginName());
        Map<String, String> restmap = null;
        try {
            Map<String, String> parm = new HashMap<String, String>();
            parm.put("mch_id", matchId); //商户号
            parm.put("partner_trade_no", "17600116666"); //商户订单号
            parm.put("nonce_str", WXPayUtil.getStringRandom(30)); //随机字符串
            InputStream in =new FileInputStream("publicKey8.pem");
			publicKey =RSAUtil.loadPublicKey(in);
			byte[] byteArr=RSAUtil.encryptData("6222020200103736589".getBytes(), publicKey);
			System.out.println(Base64Utils.encodeToString(byteArr));
			in.close();
            parm.put("enc_bank_no", Base64Utils.encodeToString(byteArr)); //收款方银行卡号
            byte[] byteArr2=RSAUtil.encryptData("朱振强".getBytes(), publicKey);
            parm.put("enc_true_name", Base64Utils.encodeToString(byteArr2)); //收款方用户名
            parm.put("bank_code", "1002"); //收款方开户行
            parm.put("amount", "1"); //收款金额
            String sign = null;
            try {
                sign = WXPayUtil.generateSignature(parm,apiKey);
            } catch (Exception e) {
                e.printStackTrace();
            }
            parm.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
            logger.info("发送的报文:" + JSON.toJSONString(parm));
            String retXml = WxHttpClientUtils.reqWithdrawalPost(WXPayConstants.TRANSFERSANDBANK_PAY, WXPayUtil.map2Xml(parm));
            restmap = WXPayUtil.xmlToMap(retXml);
            logger.info("微信提现返回:" + retXml);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        if (restmap!=null && !"".equals(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
            logger.info("提现成功：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            Map<String, String> transferMap = new HashMap<>();
            transferMap.put("partner_trade_no", restmap.get("partner_trade_no"));//商户转账订单号
            transferMap.put("payment_no", restmap.get("payment_no")); //微信订单号
            transferMap.put("payment_time", restmap.get("payment_time")); //微信支付成功时间
            System.err.println("提现成功");
            map.put("msg", 1);
            map.put("partner_trade_no",restmap.get("partner_trade_no"));
        }else {
            if (restmap!=null && !"".equals(restmap)) {
                logger.info("提现失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
            }
            System.err.println("提现失败");
            map.put("msg", 0);
        }
        return map;
    }
    
    public static void main(String[] args) {
    	
    	PublicKey publicKey = null;
		try {
			InputStream in =new FileInputStream("publicKey8.pem");
			publicKey =RSAUtil.loadPublicKey(in);
			byte[] byteArr=RSAUtil.encryptData("62222020200103736589".getBytes(), publicKey);
			System.out.println(Base64Utils.encodeToString(byteArr));
			in.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	
	}
    
    public static String getRSAInfo(){
    	Map<String, String> restmap = null;
    	String publicKey = "";
    	try {
    		SortedMap<String, String> parm = new TreeMap<String, String>();
            parm.put("mch_id", "1507157911"); //商户号
            parm.put("nonce_str", WXPayUtil.getStringRandom(30)); //随机字符串
            parm.put("sign_type", "MD5"); 
            String sign = null;
            try {
                sign = WXPayUtil.createSign("UFT-8",parm);
            } catch (Exception e) {
                e.printStackTrace();
            }
            parm.put("sign", sign);//通过签名算法计算得出的签名值，详见签名生成算法
            String retXml = WxHttpClientUtils.reqWithdrawalPost(WXPayConstants.GETPUBLICKEY, WXPayUtil.map2Xml(parm));
            restmap = WXPayUtil.xmlToMap(retXml);
            System.err.println(retXml);
            publicKey = restmap.get("pub_key").toString();
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	return publicKey;
    }
}
